package me.winter.imgop;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.io.File;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import squint.GUIManager;
import squint.SImage;
import me.winter.imgcmps.*;

/*
 * DualImageViewer  --- Loads and displays images.  Allows user to apply 
 *                      a variety of simplification algorighms to the image
 *                      pixels and see both the simplified image and the result
 *                      of attempting to restore the original by "unsimplifying"
 */
public class DualImageViewer extends GUIManager {
    // Window dimensions
    private final int WINDOW_WIDTH  = 750, WINDOW_HEIGHT = 400;
   
    // Viewer panels for the original and unsimplified versions of an image
    private ImageViewer left = new ImageViewer();
    private ImageViewer right = new ImageViewer();
    
    // Buttons used to load, compress, and compare original and unsimplified images
    private JButton load = new JButton( "Load Image" );
    private JButton compress = new JButton( "-> Simplify -> Unsimplify ->");
    private JComboBox<String> compressMethods = new JComboBox<String>();
    private JButton differ = new JButton( "Show difference" );
    
    // Menu used to select a simplification algorithm
    private JComboBox<String> methods = new JComboBox<String>();
    
    // List of simplifiers that have been placed in methods menu
    private SimplifierList simplifiers = new SimplifierList();
  
    // Dialog box used to select image files
    private JFileChooser chooser = new JFileChooser( new File( System.getProperty("user.dir")) );
    private String imgFileName;
    
    public DualImageViewer() {
      this.createWindow( WINDOW_WIDTH, WINDOW_HEIGHT );
      contentPane.setLayout( new BorderLayout() );
      
      // Place two imageviewers in a panel at CENTER of contentPane
      JPanel viewers = new JPanel();
      viewers.setLayout( new GridLayout(1,2) );
      viewers.add( left , BorderLayout.NORTH);
      viewers.add( right , BorderLayout.SOUTH);
      contentPane.add( viewers, BorderLayout.CENTER );
      
      
      // Add desired image simplifiers to menu of available algorithms
      addSimplifier( "Range Simplifier", new RangeSimplifier1( 32 ) );
      addSimplifier( "Alternate Range Simplifier", new RangeSimplifier2( 32 ) );
      addSimplifier( "Waterfall Simplifier", new WaterfallSimplifier() );
      addSimplifier( "Wavlet Simplifier", new WaveletSimplifier() );
      addSimplifier( "Recursive Wavelet Simplifier", new RecursiveWaveletSimplifier() );
      addSimplifier( "Recursive Wavelet and Waterfall", new RWaveletWaterfallSimplifier() );
      //   ......   add lines to incorporate additional simplifiers here

      // Add two compress and uncompress methods
      compressMethods.addItem("Static");
      compressMethods.addItem("Adaptive");
      
      // Add control buttons and menu to SOUTH of contentPane
      JPanel controls = new JPanel();
      controls.add( load );
      controls.add( differ );
      controls.add( compress );
      controls.add( compressMethods );
      controls.add( methods );
      contentPane.add( controls, BorderLayout.SOUTH );
    }
    
    
    // Respond to control buttons
    @Override
	public void buttonClicked( JButton which ) {
        
        if ( which == load ) {
            // Try to load a new image file
            FileFilter filter = new FileNameExtensionFilter("JPG && PNG && GIF Image",
                                    "jpg", "jpeg", "png", "gif");
            chooser.setFileFilter( filter );
            if ( chooser.showOpenDialog( this ) == JFileChooser.APPROVE_OPTION ) {
            	imgFileName = chooser.getSelectedFile().getName();
                left.setPic( new SImage( chooser.getSelectedFile().getAbsolutePath() ) );
            }

        } else if ( which == differ ) {
            SImage leftPic = left.getPic();
            SImage rightPic = right.getPic();
        
            // Compute and display the difference between and original and unsimplified image
            // (as long as they both exist and are of the same dimensions)
           if ( leftPic != null && rightPic != null &&
                 leftPic.getWidth() == rightPic.getWidth() &&
                 leftPic.getHeight() == rightPic.getHeight() ) {
                ImageViewer newWin = new ImageViewer();
                newWin.setPic( new Differencer( leftPic).filter( rightPic ) );
                newWin.createWindow( WINDOW_WIDTH, WINDOW_HEIGHT );
            }
            
        } else if ( which == compress && left.getPic() != null) {
            // Apply the simplification algorithm selected in the menu to the
            // image displayed in the left page.
            ImageViewer result = new ImageViewer( );
            result.createWindow( 300, 300 );

            String compMethod = methods.getSelectedItem().toString();
            ImageSimplifier comp = simplifiers.getSimplifier(compMethod);
            SImage simplifiedImage = comp.encode( left.getPic() );
           
            
            String fileName = imgFileName.split("\\.")[0] + "_" + compMethod;
            RgbPixels rgbs = new RgbPixels(simplifiedImage.getRedPixelArray(),
            		simplifiedImage.getGreenPixelArray(),
            		simplifiedImage.getBluePixelArray());
            
            String cm = compressMethods.getSelectedItem().toString();
            if (cm.equals("Static")) {
	            Huff huff = new Huff(rgbs.getRgbPixelsArray());
	            huff.compress(fileName);
	            
	            rgbs.setRgbPixels(huff.uncompress(fileName));
            }
            
            else { // Adaptive
	            AdaptiveHuff adaptiveHuff = new AdaptiveHuff(rgbs.getRgbPixelsArray());
	            adaptiveHuff.compress(fileName);
	            
	            AdaptiveHuff aHuff = new AdaptiveHuff();
	            rgbs.setRgbPixels(aHuff.uncompress(fileName));
            }
            
            SImage uncompressedSimpImage = new SImage(rgbs.getRedPixelArray(),
            		rgbs.getGreenPixelArray(),
            		rgbs.getBluePixelArray());
            result.setPic(uncompressedSimpImage);
            SImage decodedImage = comp.decode(uncompressedSimpImage);
//            decodedImage.saveAs("AllImages/Compression/uncompressed/" +
//            		fileName + ".png");
            right.setPic(decodedImage);
            
            
//            Huff huff = new Huff(simplifiedImage.getPixelArray());
//            huff.compress(fileName);
//            
//            result.setPic(new SImage(huff.to2DArray()));
            
            
            
//            result.setPic( simplifiedImage );
//            SImage decoded = comp.decode( result.getPic() );
////            decoded.saveAs("AllImages/Compression/uncompressed/" + fileName + ".png");
//            right.setPic( decoded );
        }
      
    }
    
    // Add an ImageSimplifier to both the list of simplifiers installed and the JComboBox
    // used to select the desired algorithm
    public void addSimplifier( String label, ImageSimplifier simp ) {
        simplifiers = new SimplifierList( label, simp, simplifiers );
        methods.addItem( label );
    }
            
}